package com.manyiaby.presenter.textgo;

import android.net.Uri;
import android.util.Log;

import io.reactivex.Observable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

import com.manyiaby.model.usermodel.MyaseUsers;
import com.manyiaby.model.usermodel.User;

import org.w3c.dom.Comment;

import java.io.File;
import java.util.Map;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.PUT;
import retrofit2.http.Part;
import retrofit2.http.Path;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;

import static android.R.attr.type;


/**
 * Created by yx on 2017/6/9.
 * Retrofit2 各种请求样式详解
 * 耐心看
 */

public interface TextBiz {

    //接口完整地址
    //http://192.168.6.2:80/GetToken?key=26F14B6F96893062FA8EB4C3DBD4852B
    //{ action: "123", device: "456",UserId: "456", Parameters: "{\"key\":\"26F14B6F96893062FA8EB4C3DBD4852B\"}" }
    //@Headers({"Content-Type: application/json", "Accept: application/json"})//需要添加头
    @POST("GetToken")
    Call<MyaseUsers> loginDate(@Body RequestBody route);

    @POST("GetToken")
    Observable<MyaseUsers> getLos(@Body RequestBody route);


    //通过  @Body 注解可以声明一个对象作为请求体发送到服务器。
//    使用 @FormUrlEncoded 注解来发送表单数据；使用 @Field注解和参数来指定每个表单项的Key，value为参数的值。
//    form-urlencoded是POST数据默认编码格式，POST过去的key-value会被编码成QueryString，格式如下:
//    name=test&gender=male&email=iefreer@live.cn
//    服务器端对接受数据的处理也很简单。
//    json一般更多用来返回数据而不是在提交数据的时候使用，通常Restful服务都会支持json/xml格式的返回数据。
//    @FormUrlEncoded将会自动将请求参数的类型调整为application/x-www-form-urlencoded，假如content传递的参数为Good Luck，那么最后得到的请求体就是
//            content=Good+Luck
//    @Field注解将每一个请求参数都存放至请求体中，还可以添加encoded参数，该参数为boolean型，具体的用法为
//    @Field(value = "book", encoded = true) String book
    //http://blog.csdn.net/androidxiaogang/article/details/53328217
    //http://blog.csdn.net/duanyy1990/article/details/52139294   中下部分有Nice阅读价值
    //http://www.jianshu.com/p/7687365aa946

    //==========================☆☆☆☆☆☆☆☆=Get样式=========☆☆☆☆☆============================
//    （一个简单的get请求）:
//    http://102.10.10.132/api/News
//    @GET("News")
//    Call<NewsBean> getItem();


//   ========================(样式2 URL中有参数）===================
//    http://102.10.10.132/api/News/1  =  http://102.10.10.132/api/News/{资讯id}
//    @GET("News/{newsId}")
//    Call<NewsBean> getItem(@Path("newsId") String newsId);

//    http://102.10.10.132/api/News/{资讯id}/{类型}
//    @GET("News/{newsId}/{type}")
//    Call<NewsBean> getItem(@Path("newsId") String newsId, @Path("type") String type);

//    =======================(样式3 参数在URL问号之后）===============================
//    http://102.10.10.132/api/News?newsId=1  http://102.10.10.132/api/News?newsId={资讯id}
//    @GET("News")
//    Call<NewsBean> getItem(@Query("newsId") String newsId);

//    http://102.10.10.132/api/News?newsId=1&type=类型1 http://102.10.10.132/api/News?newsId={资讯id}&type={类型}
//    @GET("News")
//    Call<NewsBean> getItem(@Query("newsId") String newsId, @Query("type") String type);

//    ======================样式4（多个参数在URL问号之后，且个数不确定）===================
//    http://102.10.10.132/api/News?newsId=1&type=类型1...
//    http://102.10.10.132/api/News?newsId={资讯id}&type={类型}...
//    @GET("News")
//    Call<NewsBean> getItem(@QueryMap Map<String, String> map);

//    @GET("News")
//    Call<NewsBean> getItem(@Query("newsId") String newsId， @QueryMap Map<String, String>map);


//======================☆☆☆☆===========Post=======☆☆☆☆☆☆===========================

//============================post样式1（补全式URL，post的数据只有一条reason）========================
//    http://102.10.10.132/api/News/1
//    http://102.10.10.132/api/News/{newsId}
//    @FormUrlEncoded
//    @POST("News/{newsId}")
//    这里{大括号里面的东西需要通过“path” String commentId补全
//    Call<Comment> reportComment(@Path("newsId") String commentId, @Field("reason") String reason);


//    =========================post样式2（补全URL，问号后加入access_token，post的数据只有一条reason）===
//    http://102.10.10.132/api/Comments/1?access_token=1234123
//    http://102.10.10.132/api/Comments/{newsId}?access_token={access_token}
//    @POST("News/{newsId}")
//    Call<NewsBean> reportComment(@Path("newsId") String commentId,
//                                @Query("access_token") String access_token,
//                                @Field("reason") String reason);


//    ========================post样式3（补全URL，问号后加入access_token，post一个body（对象））===========
//    http://102.10.10.132/api/Comments/1?access_token=1234123
//    http://102.10.10.132/api/Comments/{newsId}?access_token={access_token}
//    @POST("News/{newsId}")
//    Call<Comment> reportComment(@Path("newsId") String commentId,
//                                @Query("access_token") String access_token, @Body CommentBean bean);

    //    ==========================post样式4，提交多个请求参数==================
//    @FormUrlEncoded
//    @POST("News/reviews")
//    Call<NewsBean> addReviews(@FieldMap Map<String, String> fields);
//    http://102.10.10.132/api/book/reviews post一个body对象
//    @FormUrlEncoded
//    @POST("book/reviews")
//    Call<String> addReviews(@Body Reviews reviews);
//
//    public class Reviews {//将参数统一封装到类中，传一个body对象
//        public String book;
//        public String title;
//        public String content;
//        public String rating;
//    }

    //========================post样式5，上传单个文件至服务器===上传因为需要用到Multipart==================
    //创建接口实例public interface FileUploadService {
//    http://102.10.10.132/api/upload/
//    @Multipart
//    @POST("upload")
//    Call<ResponseBody> uploadFile(
//            @Part("description") RequestBody description,
//            @Part MultipartBody.Part file);

    // 上传多个文件
//    @Multipart
//    @POST("upload")
//    Call<ResponseBody> uploadMultipleFiles(
//            @Part("description") RequestBody description,
//            @Part MultipartBody.Part file1,
//            @Part MultipartBody.Part file2);
//    创建工具方法
//    public static final String MULTIPART_FORM_DATA = "multipart/form-data";
//
//    @NonNull
//    private RequestBody createPartFromString(String descriptionString) {
//        return RequestBody.create(
//                MediaType.parse(MULTIPART_FORM_DATA), descriptionString);
//    }
//
//    @NonNull
//    private MultipartBody.Part prepareFilePart(String partName, Uri fileUri) {
//        File file = File  Utils.getFile(this, fileUri);
//
//        // 为file建立RequestBody实例
//        RequestBody requestFile =
//                RequestBody.create(MediaType.parse(MULTIPART_FORM_DATA), file);
//
//        // MultipartBody.Part借助文件名完成最终的上传
//        return MultipartBody.Part.createFormData(partName, file.getName(), requestFile);
//    }

//    接下来我们还需要在Activity和Fragment中使用两个工具方法，实现最终的上传文件代码了
//    Uri file1Uri = ... // 从文件选择器或者摄像头中获取
//    Uri file2Uri = ...
//
//    // 创建上传的service实例
//    FileUploadService service =
//            ServiceGenerator.createService(FileUploadService.class);
//
//    // 创建文件的part (photo, video, ...)
//    MultipartBody.Part body1 = prepareFilePart("video", file1Uri);
//    MultipartBody.Part body2 = prepareFilePart("thumbnail", file2Uri);
//
//    // 添加其他的part
//    RequestBody description = createPartFromString("hello, this is description speaking");
//
//    // 最后执行异步请求操作
//    Call<ResponseBody> call = service.uploadMultipleFiles(description, body1, body2);
//    call.enqueue(new Callback<ResponseBody>() {
//        @Override
//        public void onResponse(Call<ResponseBody> call,
//                Response<ResponseBody> response) {
//            Log.v("Upload", "success");
//        }
//        @Override
//        public void onFailure(Call<ResponseBody> call, Throwable t) {
//            Log.e("Upload error:", t.getMessage());
//        }
//    });
//
//


//====================☆☆☆☆☆☆======delete样式=========☆☆☆☆☆===============

//    =========================DELETE 样式1（需要补全URL）===============
//    http://102.10.10.132/api/Comments/1
//    http://102.10.10.132/api/Comments/{newsId}{access_token}
//    @DELETE("Comments/{commentId}")  //accountId补全到{commentId}中
//    Call<ResponseBody> deleteNewsCommentFromAccount(@Path("accountId") String accountId);


//    ===========================样式2（需要补全URL，问号后加入access_token）=============
//    http://102.10.10.132/api/Comments/1?access_token=1234123
//    http://102.10.10.132/api/Comments/{newsId}?access_token={access_token}
//    @DELETE("Comments/{commentId}")
//    Call<ResponseBody> deleteNewsCommentFromAccount(@Path("accountId") String accountId,
//            @Query("access_token") String access_token);

//====================☆☆☆☆=====Put样式-======☆☆☆☆☆☆=========================================

//    ==============PUT（这个请求很少用到，例子就写一个：补全URL，问号后面加access_token,提交一个Body对象）========
//    http://102.10.10.132/api/Accounts/1
//    http://102.10.10.132/api/Accounts/{accountId}
//    @PUT("Accounts/{accountId}")
//    Call<ExtrasBean> updateExtras(@Path("accountId") String accountId,
//                                  @Query("access_token") String access_token, @Body ExtrasBean bean);


    //=====================Retrofit同步异步问题===========
    //同步是:在ui线程直接执行
//    Retrofit retrofit = RetrofitManager.getRetrofit();
//    GitHubService service = retrofit.create(GitHubService.class);
//    Call<User> example = service.userInfo("ttdevs");
//    Response<User> response = example.execute();
//    print(response.body().getName());
    //异步是: 在子线程中执行，完成后通过回调回到ui线程
//    在Callback中获取到response后进行处理操作
    //理由:
    //由于同步请求会阻塞当前线程，Android的设计逻辑不能在主线程中发起网络请求（可能会导致ANR），
    // 所以我们比较常见的都是异步形式的网络请求。但是，有时候我们在工作线程中处理一些网络请求的时候，
    // 可以接受阻塞的情况（这个时候使用回调往往会使问题复杂化），那么我们就可以使用同步的方式来发起网络请求，
    // 比如，在使用Rxjava封装某个网络功能的逻辑是（如图片上传）我们就可以同步形式的网络请求。


}
